package com.jswitch.server.transaction;

import cn.hutool.core.collection.ListUtil;
import com.jswitch.server.factory.SipMessageStrategy;
import com.jswitch.server.msg.SipMessageEvent;
import com.jswitch.server.process.requset.InviteSipMessageProcess;
import com.jswitch.sip.*;
import com.jswitch.sip.header.AllowList;
import io.netty.channel.ChannelHandlerContext;
import lombok.Data;

import java.text.ParseException;

/**
 * @author danmo
 * @date 2024-07-04 14:23
 **/
@Data
public class SipTransactionUser implements TransactionUser {

    private SipMessageStrategy strategy;

    public SipTransactionUser(SipMessageStrategy strategy) {
        this.strategy = strategy;
    }

    @Override
    public void onRequest(SipRequest request, ServerSipTransaction transaction) {
        // 如果收到的请求是CANCEL请求，事务进入终止状态
        if (Request.CANCEL.equals(request.getMethod())) {
            transaction.terminate();
        } else {
            // 交给事务处理请求
            transaction.processRequest(request);
        }
    }

    @Override
    public void onResponse(SipResponse response, ClientSipTransaction transaction) {
        // 交给客户端事务处理响应
        transaction.processResponse(response);
    }

    @Override
    public void onTimeout(Transaction transaction) {
        // 处理事务超时，通常清理事务相关的资源
        transaction.terminate();
    }

    @Override
    public void onCancel(Transaction transaction) {
        // 处理CANCEL请求，标记事务为已取消并终止
        transaction.cancel();
        transaction.terminate();
    }

    @Override
    public void sendRequest(SipRequest request, ChannelHandlerContext ctx) {
        strategy.handleRequest(new SipMessageEvent(request, ctx));
    }

    @Override
    public void sendResponseError(SipMessageEvent event) {
        // 创建一个通用的500内部服务器错误响应
        SipResponse errorResponse = ((SipRequest)event.getMessage()).createResponse(SipResponse.SERVER_INTERNAL_ERROR);
        // 发送错误响应
        sendToTransportLayer(event.getCtx(), errorResponse);
    }

    @Override
    public SipResponse generateFinalResponse(SipRequest sipRequest) {
        // 根据请求的不同生成相应的响应
        String method = sipRequest.getMethod();

        if (method.equals(Request.BYE)) {
            // 处理BYE请求，通常返回200 OK
            return sipRequest.createResponse(SipResponse.OK);
        } else if (method.equals(Request.OPTIONS)) {
            // 处理OPTIONS请求，返回200 OK并包含一些支持的功能信息
            SipResponse response = sipRequest.createResponse(SipResponse.OK);
            try {
                AllowList allows = new AllowList();
                allows.setMethods(ListUtil.toList("INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "REFER", "NOTIFY", "MESSAGE", "SUBSCRIBE", "INFO"));
                response.setHeader(allows);
            } catch (ParseException e) {
            }
            return response;
        } else if (method.equals(Request.CANCEL)) {
            // 处理CANCEL请求，通常返回200 OK
            return sipRequest.createResponse(SipResponse.OK);
        } else if (method.equals(Request.MESSAGE)) {
            // 处理MESSAGE请求，可能返回200 OK或其他根据业务逻辑的响应
            return sipRequest.createResponse(SipResponse.OK);
        } else {
            // 对于未知或不支持的请求方法，返回405 Method Not Allowed
            SipResponse response = sipRequest.createResponse(SipResponse.METHOD_NOT_ALLOWED);
            try {
                AllowList allows = new AllowList();
                allows.setMethods(ListUtil.toList("INVITE", "ACK", "CANCEL", "OPTIONS", "BYE", "REFER", "NOTIFY", "MESSAGE", "SUBSCRIBE", "INFO"));
                response.setHeader(allows);
            } catch (ParseException e) {
            }
            return response;
        }
    }

    private void sendToTransportLayer(ChannelHandlerContext ctx, SipMessage message) {
        // 将SIP消息通过Netty的ChannelHandlerContext发送到网络层
        ctx.writeAndFlush(message);
    }
}
